package com.sunshine.wrongquestionset.activity.main

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat.getColor
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.github.mikephil.charting.animation.Easing
import com.github.mikephil.charting.components.AxisBase
import com.github.mikephil.charting.components.Legend
import com.github.mikephil.charting.components.XAxis
import com.github.mikephil.charting.data.*
import com.github.mikephil.charting.formatter.ValueFormatter
import com.sunshine.wrongquestionset.R
import com.sunshine.wrongquestionset.callback.OnRefreshListener
import com.sunshine.wrongquestionset.room.entity.QuestionEntity
import com.sunshine.wrongquestionset.room.entity.QuestionInfoEntity
import com.sunshine.wrongquestionset.room.entity.QuestionTypeEntity
import com.sunshine.wrongquestionset.room.entity.WrongQuestionBean
import com.sunshine.wrongquestionset.utils.AnalyzerUtils
import kotlinx.android.synthetic.main.fragment_analyzer.*
import java.text.DecimalFormat

/**
 * 对于分析界面，我们应该分析什么？
 *
 * 1.总练习题目数量，练习分数比，就是练习历史中的信息
 * 2.最近练习题目数量折线图
 *
 * 我们不应该将分析固定化，而是采用黑盒模式：即给定一个输入，然后从输出结果分析即可
 */
class AnalyzerFragment : Fragment() {

    private lateinit var viewModel: MainViewModel
    //百分数保留2位
    private val decimalFormat = DecimalFormat("0.##%")

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_analyzer, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(requireActivity().application)).get(MainViewModel::class.java)

//        val list = ArrayList<BarEntry>()
//        //添加数据
//        list.add(BarEntry(1.0f, 3.0f))
//        list.add(BarEntry(2.0f, 8.0f))
//        list.add(BarEntry(3.0f, 6.0f))
//        list.add(BarEntry(4.0f, 9.0f))
//        val barDataSet = BarDataSet(list, "测试数据")
//        val barData = BarData(barDataSet)
//        barChart.data = barData
//        barChart.description.isEnabled = false //隐藏右下角英文
//        barChart.xAxis.position = XAxis.XAxisPosition.BOTTOM //X轴的位置 默认为上面
//        barChart.axisRight.isEnabled = false //隐藏右侧Y轴   默认是左右两侧都有Y轴
//
//        val list1 = ArrayList<PieEntry>()
//        list1.add(PieEntry(56.0f, "男性"))
//        list1.add(PieEntry(44.0f, "女性"))
//        val pieDataSet = PieDataSet(list1, "")
//        val pieData = PieData(pieDataSet)
//        pieChart.data = pieData
//        pieDataSet.setColors(Color.RED, Color.BLUE) //设置各个数据的颜色
//
//        val list2 = ArrayList<Entry>()
//        list2.add(Entry(0.0f, 7.0f)) //其中两个数字对应的分别是   X轴   Y轴
//        list2.add(Entry(1.0f, 10.0f))
//        list2.add(Entry(2.0f, 12.0f))
//        list2.add(Entry(3.0f, 6.0f))
//        list2.add(Entry(4.0f, 3.0f))
//
//        //list是你这条线的数据  "语文" 是你对这条线的描述（也就是图例上的文字）
//        val lineDataSet = LineDataSet(list2, "语文")
//        val lineData = LineData(lineDataSet)
//        lineChart.setData(lineData)
//
//        //简单美化
//
//        //   X轴所在位置   默认为上面
//        lineChart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM)
//        //隐藏右边的Y轴
//        lineChart.getAxisRight().setEnabled(false)
    }

    /**
     * ViewPager2 本身就支持对实际可见的 Fragment 才调用 onResume 方法。
     * 所以直接懒加载就可以了
     */
    override fun onResume() {
        super.onResume()
        (requireActivity() as MainActivity).getLoginUserId(object : OnRefreshListener<String>() {
            override fun onUpdate(obj: String) {
                super.onUpdate(obj)

                //首先获取用户下所有错题
                viewModel.getWrongQuestionByUserId(obj).observe(viewLifecycleOwner, Observer {
                    updateLastDayExerciseSituation(it)
                })

                //获取用户所有题目
                viewModel.getQuestion(obj).observe(viewLifecycleOwner, Observer {
                    //获取题目类型
                    viewModel.getAllQuestionType().observe(viewLifecycleOwner, Observer {questionTypeList ->
                        updateQuestionDistribution(it)
                        updateQuestionTypePart(it, questionTypeList)
                    })

                })

                viewModel.getTodayWrongQuestion().observe(viewLifecycleOwner, Observer {
                    updateInfo(it)
                })

                //获取信息
                viewModel.getAllQuestionInfo().observe(viewLifecycleOwner, Observer {
                    updateLastDayExerciseFamiliaritySituation(it)
                })
            }
        })
    }

    @SuppressLint("SetTextI18n")
    private fun updateInfo(list: List<WrongQuestionBean>?) {
        textView_today_exercise_info.text = "今日练习记录"

        textView_count_info.text = "${list?.size?:0}"

        var score = 0.0f
        var totalScore = 0.0f
        list?.forEach {
            score += it.score
            totalScore += it.totalScore
        }

        textView_score_info.text = "$score/$totalScore"

        val chartList = ArrayList<PieEntry>()
        chartList.add(PieEntry(score, "得分"))
        chartList.add(PieEntry(totalScore - score, "失分"))
        val pieDataSet = PieDataSet(chartList , "总得分占比")
        val pieData = PieData(pieDataSet)
        pieChart_score.data = pieData
        pieDataSet.setColors(getColor(requireContext(), R.color.chart_color_2), getColor(requireContext(), R.color.chart_color_1)) //设置各个数据的颜色

//        val description = Description()
//        description.text = "得分占比饼状图"
        pieChart_score.description = null

        pieChart_score.animateY(1000, Easing.EaseInOutQuad)

        pieChart_score.invalidate()
    }

    /**
     * 刷新前几天做题情况
     */
    @SuppressLint("SetTextI18n")
    private fun updateLastDayExerciseSituation(it: List<WrongQuestionBean>?) {
        val days = 5

        textView_exercise_count.text = "近${days}日做题数量"

        val bean = AnalyzerUtils.getLastDayExerciseSituation(it, days)
        val entryList = bean.entryList
        val xTimeMap = bean.xTimeMap

        val barDataSet = BarDataSet(entryList, "做题数量")

        //设置柱状图的配置
        barDataSet.apply {
            //数值显示为整数
            valueFormatter = object : ValueFormatter() {
                override fun getBarLabel(barEntry: BarEntry?): String {
                    if (barEntry == null) return ""
                    return barEntry.y.toInt().toString()
                }
            }

            valueTextSize = 12.0f
//            //折线过渡为圆角
//            mode = LineDataSet.Mode.CUBIC_BEZIER
            //折线的颜色，设置为主题色
            color = requireContext().getColor(R.color.google_blue_600)
//            //圆点颜色
//            setCircleColor(requireContext().getColor(R.color.google_blue_600))
        }

        val barData = BarData(barDataSet)

        //整图的配置
        barChart_exercise_count.apply {
            data = barData
            description = null
            //是否绘制X轴上的网格线（背景里面的竖线）
            xAxis.setDrawGridLines(false)
            //是否绘制Y轴上的网格线（背景里面的横线）
            axisLeft.setDrawGridLines(false)

            //设置不支持手势缩放
            setScaleEnabled(false)

            //X轴位置
            xAxis.position = XAxis.XAxisPosition.BOTTOM

            //设置X轴个数
            xAxis.setLabelCount(days, false)
            //设置Y轴个数
            axisLeft.setLabelCount(6, false)

            //设置X轴坐标为日期
            xAxis.valueFormatter = object : ValueFormatter() {
                override fun getAxisLabel(value: Float, axis: AxisBase?): String {
                    return xTimeMap[value.toInt()]?:""
                }
            }

            //设置Y轴坐标为整数
            axisLeft.valueFormatter = object : ValueFormatter() {
                override fun getAxisLabel(value: Float, axis: AxisBase?): String {
                    return if (value.compareTo(value.toInt()) == 0) value.toInt().toString() else ""
                }
            }

            //隐藏右边的Y轴
            axisRight.isEnabled = false
            //设置y轴最小从0开始，因为做题数量都是正数
            axisLeft.mAxisMinimum = 0.0f
            //设置最大值为最大的练习次数
            axisLeft.mAxisMaximum = bean.maxY

            //Y轴动画
            animateY(1000)

            invalidate()
        }
    }

    /**
     * 刷新题目熟悉程度分布
     */
    private fun updateQuestionDistribution(list: List<QuestionEntity>?) {
        textView_exercise_distribution_familiarity.text = "熟悉程度分布"

        val pieEntryList = AnalyzerUtils.getQuestionDistribution(list)

        pieChart_exercise_distribution_familiarity.apply {
            val pieDataSet = PieDataSet(pieEntryList, "熟悉程度分布")
            val pieData = PieData(pieDataSet)

            pieData.apply {
                //设置问题颜色
                setValueTextColor(Color.WHITE)
                setValueTextSize(12.0f)

                //设置格式
                setValueFormatter(object : ValueFormatter() {
                    override fun getPieLabel(value: Float, pieEntry: PieEntry?): String {
                        return value.toInt().toString()
                    }
                })

            }

            pieDataSet.setColors(
                getColor(requireContext(), R.color.chart_color_1),
                getColor(requireContext(), R.color.chart_color_2),
                getColor(requireContext(), R.color.chart_color_3),
                getColor(requireContext(), R.color.chart_color_4),
                getColor(requireContext(), R.color.chart_color_5)
            )

//            val description = Description()
//            description.text = "熟悉程度分布饼状图"
            this.description = null

            data = pieData

            //图例方向和位置
            legend.apply {
                orientation = Legend.LegendOrientation.VERTICAL
                verticalAlignment = Legend.LegendVerticalAlignment.TOP
            }

            animateY(1000, Easing.EaseInOutQuad)
            invalidate()
        }
    }

    /**
     * 刷新前几天熟悉度变化
     */
    @SuppressLint("SetTextI18n")
    private fun updateLastDayExerciseFamiliaritySituation(it: List<QuestionInfoEntity>?) {
        val days = 5

        textView_exercise_familiarity.text = "近${days}日熟悉程度变化"

        val bean = AnalyzerUtils.getLastDayExerciseFamiliaritySituation(it, days)
        val entryList = bean.entryList
        val xTimeMap = bean.xTimeMap

        val lineDataSet = LineDataSet(entryList, "熟悉程度")

        //设置折线的配置
        lineDataSet.apply {
            //折线过渡为圆角
            mode = LineDataSet.Mode.CUBIC_BEZIER
            //折线的颜色，设置为主题色
            color = requireContext().getColor(R.color.google_blue_600)
            //圆点颜色
            setCircleColor(requireContext().getColor(R.color.google_blue_600))

            valueTextSize = 8.0f

            valueFormatter = object : ValueFormatter() {
                override fun getPointLabel(entry: Entry?): String {
                    if (entry == null) return ""
                    return decimalFormat.format(entry.y)
                }
            }
        }

        val lineData = LineData(lineDataSet)

//        val description = Description()
//        description.text = "最近${days}天熟悉程度折线图"

        //整图的配置
        lineChart_exercise_familiarity.apply {
            data = lineData
            description = null
            //是否绘制X轴上的网格线（背景里面的竖线）
            xAxis.setDrawGridLines(false)
            //是否绘制Y轴上的网格线（背景里面的横线）
            axisLeft.setDrawGridLines(false)

            //设置不支持手势缩放
            setScaleEnabled(false)

            //X轴位置
            xAxis.position = XAxis.XAxisPosition.BOTTOM

            //设置X轴个数
            xAxis.setLabelCount(days, false)
            //设置Y轴个数
            axisLeft.setLabelCount(6, false)

            //设置X轴坐标为日期
            xAxis.valueFormatter = object : ValueFormatter() {
                override fun getAxisLabel(value: Float, axis: AxisBase?): String {
                    return xTimeMap[value.toInt()]?:""
                }
            }

            axisLeft.valueFormatter = object : ValueFormatter() {
                override fun getAxisLabel(value: Float, axis: AxisBase?): String {
                    return decimalFormat.format(value)
                }
            }

            //隐藏右边的Y轴
            axisRight.isEnabled = false
            //设置y轴最小从0开始，因为做题数量都是正数，不能设置，设置后会有问题
//            axisLeft.mAxisMinimum = 0.0f
//            //设置最大值
//            axisLeft.mAxisMaximum = 1.0f

            //Y轴动画
            animateY(1000)

            invalidate()
        }
    }

    /**
     * 刷新题目类型组成饼状图
     */
    private fun updateQuestionTypePart(list: List<QuestionEntity>?, typeList: List<QuestionTypeEntity>?) {
        textView_exercise_type_part.text = "题目组成"

        val pieEntryList = AnalyzerUtils.getWrongQuestionTypePart(list, typeList)

        pieChart_exercise_type_part.apply {
            val pieDataSet = PieDataSet(pieEntryList, "题目组成")
            val pieData = PieData(pieDataSet)

            pieData.apply {
                //设置问题颜色
                setValueTextColor(Color.WHITE)
                setValueTextSize(12.0f)

                //设置格式
                setValueFormatter(object : ValueFormatter() {
                    override fun getPieLabel(value: Float, pieEntry: PieEntry?): String {
                        return value.toInt().toString()
                    }
                })

            }

            pieDataSet.setColors(
                getColor(requireContext(), R.color.chart_color_1),
                getColor(requireContext(), R.color.chart_color_2),
                getColor(requireContext(), R.color.chart_color_3),
                getColor(requireContext(), R.color.chart_color_4)
            )

//            val description = Description()
//            description.text = "错题组成饼状图"
            this.description = null

            data = pieData

            //图例方向
            legend.apply {
                orientation = Legend.LegendOrientation.VERTICAL
                verticalAlignment = Legend.LegendVerticalAlignment.TOP
            }

            animateY(1000, Easing.EaseInOutQuad)
            invalidate()
        }
    }
}